import { Effect } from 'dva';
import { Reducer } from 'redux';
import { produce, Draft } from 'immer';

import {
  getDeviceManagerData,
  getDeviceCollectionList,
  getDeviceType,
  getAnalysisData,
  getAnalysisAlamData,
  problemPointDetails,
  matchChildsByParents
} from '@/services/device';
import { getAreaOptions } from '@/services/dict';
import { GetFieldDecoratorOptions } from 'antd/es/form/Form';
import { Moment } from 'moment';

interface DynamicOptionType {
  itemValue: string | number | boolean;
  itemName: string;
}

export interface DynamicFormType {
  label: string;
  fieldName: string;
  type: string;
  rules?: GetFieldDecoratorOptions['rules'];
  defaultValue?: string | number | boolean;
  readOnly?: boolean;
  singleOption?: DynamicOptionType;
  MultipleOption?: DynamicOptionType;
}

export interface DeviceInfo {
  brandNo: string;
  createId: number;
  createTime: string | Moment;
  deleteFalg: number;
  departmentId: number;
  deviceId: number;
  deviceName: string;
  deviceState: number;
  deviceTypeNo: number;
  deviceTypeParentNo: number;
  extendedField: string;
  firstTreeTypeId: number;
  groupId: number;
  mainImage: string;
  maintenanceCycle: string;
  model: string;
  stateCode: number;
  positionDetails: string;
  productionCompany: string;
  productionTime: string | Moment;
  purchaseTime: string | Moment;
  remarks: string;
  serialNumber: string;
  serviceLife: string;
  sort: number;
  specs: string;
  supplyCompany: string;
  treeTypeId: number;
  unitNameId: number;
  updateId: number;
  updateTime: string | Moment;
  useTime: string | Moment;
  useUser: string;
}

export interface DeviceCollectionItem {
  deviceId: string;
  deviceImg: string; // 图片地址
  deviceName: string; // 设备名称
  deviceTypeName: string; // 设备种类
  deviceTypeNo: number; // 设备类型编号
  deviceTypeParentNo: string;
  treeTypeName: string | null; // 安装位置
  brandName: string; // 品牌名称
  serialNumber: string; // 序列号
  deviceState: number; // 设备状态
  stateCode: number; // 在线状态
}

export interface Device {
  deviceCount: number; // 设备数量
  deviceTypeName: string; // 设备种类名称
  deviceAlamToDay: string; // 今日报警
  serialNumber: string; // 完好率
  deviceTypeNo: number; // 资产编号
}

// 统计
export interface Statistics {
  deviceTypeParentNo: any;
  deviceState: any;
  deviceSonTypeNo: any;
  deviceCount?: number; // 设备总数
  intactRate?: string; // 设备完好率
  deviceAlamCount?: number; // 告警中心
}

// 设备类型
export interface DeviceTypeItem {
  deviceTypeName: string; // 设备父类名称
  deviceTypeNo: number; // 设备父类编号
  extendedField: string; // 额外json数据 动态表单
}

export interface AreaOptionItem {
  treeName: string;
  treeTypeId: number;
}

export interface Analysis {
  error?: number;
  errorId?: [];
  toDays?: [];
  toType?: [];
  total?: number;
  wellPercent?: string;
}
export interface ProDetails {
  deviceId?: string;
  deviceTypeParentNo?: string;
  deviceTypeNo?: string;
  mainImage?: string;
  firstTreeTypeId?: string;
  treeTypeId?: string;
  positionDetails?: string;
  deviceName?: string;
  brandNo?: string;
  serialNumber?: string;
  model?: string;
  specs?: string;
  productionCompany?: string;
  productionTime?: string;
  supplyCompany?: string;
  purchaseTime?: string;
  serviceLife?: string;
  maintenanceCycle?: string;
  useUser?: string;
  departmentId?: string;
  useTime?: string;
  unitNameId?: string;
  extendedField?: string;
  remarks?: string;
  deviceState?: string;
  stateCode?: string;
  sort?: string;
  deleteFalg?: string;
  createTime?: string;
  createId?: string;
  updateTime?: string;
  updateId?: string;
  groupId?: string;
}
export interface ParentChilds {
  deviceTypeName?: string;
  deviceTypeNo: number;
  deviceTypeParentNo: number;
  extendedField: string;
}
export interface DeviceModelState {
  deviceList: Device[];
  statistics: Statistics;
  deviceCollection: DeviceCollectionItem[];
  deviceTypeNoOptions: DeviceTypeItem[];
  selectDeviceTypeNo: number;
  areaOptions: AreaOptionItem[];
  deviceCollectionTotal: number;
  getAnalysisData: Analysis;
  getAnalysisAlamData: Analysis;
  problemPointDetails: ProDetails;
  matchChildsByParents: ParentChilds[];
  activeTab: string;
  clearChildren: any[];
  clearChildrenList: any[];
  deviceCollectionListId: any;
  deviceTypeNoId: any;
  deviceName: any;
  deviceId: any;
  deviceState: any;
}

export interface DeviceModelType {
  namespace: string;
  state: DeviceModelState;
  effects: {
    initDeviceManger: Effect;
    filterDeviceCollection: Effect;
    getDeviceTypeNoOptions: Effect;
    setSelectDeviceTypeNo: Effect;
    getAnalysisData: Effect;
    getAnalysisAlamData: Effect;
    getAreaOptions: Effect;
    problemPointDetails: Effect;
    matchChildsByParents: Effect;
    setActiveTab: Effect;
    clearChildren:Effect;
    clearChildrenList: Effect;
    deviceTypeNoId: Effect;
    deviceTypeNoIdClear: Effect;
    changeDeviceCollectionList:Effect;
    changeDeviceName: Effect;
    changeDeviceId: Effect;
    changeDeviceIdClear: Effect;
    changeDeviceState: Effect;
    deviceSearchClear: Effect;
  };
  reducers: {
    changeDM_deviceList: Reducer;
    changeDM_statistics: Reducer;
    changeDM_deviceCollection: Reducer;
    setDeviceTypeNoOptions: Reducer;
    setSelectDeviceTypeNo: Reducer;
    setAreaOptions: Reducer;
    change_getAnalysisData: Reducer;
    change_getAnalysisAlamData: Reducer;
    change_problemPointDetails: Reducer;
    change_matchChildsByParents: Reducer;
    setActiveTab: Reducer;
    clearChildren:Reducer;
    clearChildrenList: Reducer;
    deviceTypeNoId: Reducer;
    deviceTypeNoIdClear: Reducer;
    changeDeviceCollectionList: Reducer;
    changeDeviceName: Reducer;
    changeDeviceId: Reducer;
    changeDeviceIdClear: Reducer;
    changeDeviceState: Reducer;
    deviceSearchClear: Reducer;
  };
}

const Model: DeviceModelType = {
  namespace: 'device',

  state: {
    deviceList: [],
    statistics: {},
    deviceCollection: [],
    deviceCollectionTotal: 0,
    deviceTypeNoOptions: [],
    areaOptions: [],
    selectDeviceTypeNo: NaN,
    getAnalysisData: {},
    getAnalysisAlamData: {},
    problemPointDetails: {},
    matchChildsByParents: [],
    activeTab: '',
    deviceCollectionListData: '',
    deviceTypeNoId: '',
    deviceName: '',
    deviceId: '',
    deviceState: '',
  },

  effects: {
    *initDeviceManger({}, { call, put }) {
      const [err, data] = yield call(getDeviceManagerData);
      if(!err) {
        yield put({
          type: 'changeDM_deviceList',
          payload: data.deviceCountVos,
        });
        yield put({
          type: 'changeDM_statistics',
          payload: data.headVo,
        });
      }
    },
    *filterDeviceCollection({ payload }, { call, put }) {
      const [err, {total, rows}] = yield call(getDeviceCollectionList, payload);
      if(!err) {
        yield put({
          type: 'changeDM_deviceCollection',
          payload: { data: rows, total: total },
        });
      }
    },
    *getAnalysisData({ payload }, { call, put }) {
      const [err, data] = yield call(getAnalysisData, payload);
      // console.log(dat)
      data.errorId = data.errorId.map((e:string) => {
        return {
          id: e,
          top: Math.random() * 350,
          left: Math.random() * 350,
        };
      })
      if(!err) yield put({ type: 'change_getAnalysisData', payload: data });
    },
    *getAnalysisAlamData({ payload }, { call, put }) {
      const [err, data] = yield call(getAnalysisAlamData, payload);
      if(!err) yield put({ type: 'change_getAnalysisAlamData', payload: data });
    },
    *getDeviceTypeNoOptions({ payload }, { call, put }) {
      const [err, data] = yield call(getDeviceType, payload);
      if(!err) yield put({ type: 'setDeviceTypeNoOptions', payload: data });
    },
    *getAreaOptions({}, { call, put }) {
      const [err, data] = yield call(getAreaOptions);
      if(!err) yield put({ type: 'setAreaOptions', payload: data });
    },
    setSelectDeviceTypeNo({ payload }, { call, put }) {
      put({ type: 'setSelectDeviceTypeNo', payload });
    },
    *problemPointDetails({ payload }, { call, put }) {
      const [err, data] = yield call(problemPointDetails, payload);
      if(!err) yield put({ type: 'change_problemPointDetails', payload: data });
    },
    *matchChildsByParents({ payload }, { call, put }) {
      const [err, data] = yield call(matchChildsByParents, payload);
      if(!err) yield put({ type: 'change_matchChildsByParents', payload: data });
    },
    clearChildren({}, { put }) {
      put({ type: 'clearChildren' });
    },
    setActiveTab({ payload }, { put }) {
      put({ type: 'setActiveTab', payload });
    },
    changeDeviceCollectionList({ payload }, { put }) {
      console.log(payload);
      put({ type: 'changeDeviceCollectionList', payload });
    },
    clearChildrenList({}, { put }) {
      put({ type: 'clearChildrenList' });
    },
    deviceTypeNoId({payload}, { put }) {
      put({ type: 'deviceTypeNoId', payload });
    },
    deviceTypeNoIdClear({ put }) {
      put({ type: 'deviceTypeNoIdClear', payload });
    },
    changeDeviceName({ payload }, { put }) {
      put({ type: 'changeDeviceName', payload });
    },
    changeDeviceId({ payload }, { put }) {
      put({ type: 'changeDeviceId', payload });
    },
    changeDeviceIdClear({ payload }, { put }) {
      put({ type: 'changeDeviceIdClear', payload });
    },
    changeDeviceState({ payload }, { put }) {
      put({ type: 'changeDeviceState', payload });
    },
    deviceSearchClear({ put }) {
      put({ type: 'deviceSearchClear', payload });
    },
  },

  reducers: {
    changeDM_deviceList: produce((draft: Draft<DeviceModelState>, { payload }): void => {
      draft.deviceList = payload;
    }),
    changeDM_statistics: produce((draft: Draft<DeviceModelState>, { payload }): void => {
      draft.statistics = payload;
    }),
    changeDM_deviceCollection: produce((draft: Draft<DeviceModelState>, { payload }): void => {
      draft.deviceCollection = payload.data;
      draft.deviceCollectionTotal = +payload.total;
    }),
    change_getAnalysisData: produce((draft: Draft<DeviceModelState>, { payload }): void => {
      draft.getAnalysisData = payload;
    }),
    change_getAnalysisAlamData: produce((draft: Draft<DeviceModelState>, { payload }): void => {
      draft.getAnalysisAlamData = payload;
    }),
    change_problemPointDetails: produce((draft: Draft<DeviceModelState>, { payload }): void => {
      draft.problemPointDetails = payload;
    }),
    change_matchChildsByParents: produce((draft: Draft<DeviceModelState>, { payload }): void => {
      draft.matchChildsByParents = payload;
    }),
    clearChildren: produce((draft: Draft<DeviceModelState>, {}): void => {
      draft.matchChildsByParents = [];
    }),
    setDeviceTypeNoOptions: produce((draft: Draft<DeviceModelState>, { payload }): void => {
      draft.deviceTypeNoOptions = payload;
    }),
    setAreaOptions: produce((draft: Draft<DeviceModelState>, { payload }): void => {
      draft.areaOptions = payload;
    }),
    setSelectDeviceTypeNo: produce((draft: Draft<DeviceModelState>, { payload }): void => {
      draft.selectDeviceTypeNo = payload;
    }),
    setActiveTab: produce((draft: Draft<DeviceModelState>, { payload }): void => {
      draft.activeTab = payload;
    }),
    changeDeviceCollectionList: produce((draft: Draft<DeviceModelState>, { payload }): void => {
      draft.deviceCollectionListData = payload;
    }),
    clearChildrenList: produce((draft: Draft<DeviceModelState>, {}): void => {
      draft.deviceCollection = {};
      draft.deviceCollectionTotal = '';
    }),
    deviceTypeNoIdClear: produce((draft: Draft<DeviceModelState>, { payload }): void => {
      draft.deviceTypeNoId = '';
    }),
    deviceTypeNoId: produce((draft: Draft<DeviceModelState>, { payload }): void => {
      draft.deviceTypeNoId = payload.e;
    }),
    deviceSearchClear: produce((draft: Draft<DeviceModelState>, { payload }): void => {
      draft.deviceName = '';
      draft.deviceId = '';
      draft.deviceState = '';
    }),
    changeDeviceName: produce((draft: Draft<DeviceModelState>, { payload }): void => {
      draft.deviceName = payload;
    }),
    changeDeviceId: produce((draft: Draft<DeviceModelState>, { payload }): void => {
      draft.deviceId = payload;
    }),
    changeDeviceIdClear: produce((draft: Draft<DeviceModelState>, { payload }): void => {
      draft.deviceId = '';
    }),
    changeDeviceState: produce((draft: Draft<DeviceModelState>, { payload }): void => {
      draft.deviceState = payload;
    }),
  },
};

export default Model;
